package com.summerbird.mallchat.common.common.aspect;

import com.summerbird.mallchat.common.chat.service.strategy.frequency.FrequencyControlDTO;
import com.summerbird.mallchat.common.chat.service.strategy.frequency.FrequencyControlUtil;
import com.summerbird.mallchat.common.common.annotation.FrequencyControl;
import com.summerbird.mallchat.common.common.annotation.FrequencyControlContainer;
import com.summerbird.mallchat.common.common.exception.BusinessException;
import com.summerbird.mallchat.common.common.exception.CommonErrorEnum;
import com.summerbird.mallchat.common.common.utils.RedisUtils;
import com.summerbird.mallchat.common.common.utils.RequestHolder;
import com.summerbird.mallchat.common.common.utils.SpElUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Aspect
@Slf4j
public class FrequencyControlAspect {

    @Around("@annotation(com.summerbird.mallchat.common.common.annotation.FrequencyControl) || @annotation(com.summerbird.mallchat.common.common.annotation.FrequencyControlContainer)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        FrequencyControl[] frequencyControls = method.getAnnotationsByType(FrequencyControl.class);
        // key -> FrequencyControl
        Map<String, FrequencyControl> keyMap = new HashMap<>(frequencyControls.length);
        // 组装key
        for (int i = 0; i < frequencyControls.length; i++) {
            FrequencyControl frequencyControl = frequencyControls[i];
            //默认方法限定名+注解排名（可能多个）
            String prefix = StringUtils.isBlank(frequencyControl.prefixKey()) ? SpElUtils.getMethodKey(method) + ":index:" + i : frequencyControl.prefixKey();
            String key = "";
            switch (frequencyControl.target()){
                case EL:
                    key = SpElUtils.parseSpEl(method, joinPoint.getArgs(), frequencyControl.spEL());
                    break;
                case IP:
                    key = RequestHolder.get().getIp();
                    break;
                case UID:
                    key = RequestHolder.get().getUid().toString();
            }
            keyMap.put(prefix + ":" + key, frequencyControl);
        }
        // 将注解的参数转换为编程式调用需要的参数
        List<FrequencyControlDTO> frequencyControlDTOS = keyMap.entrySet().stream().map(entrySet -> buildFrequencyControlDTO(entrySet.getKey(), entrySet.getValue())).collect(Collectors.toList());
        // 调用编程式注解
        return FrequencyControlUtil.executeWithFrequencyControlList(frequencyControls[0].strategyType().getName(), frequencyControlDTOS, joinPoint::proceed);

    }

    private FrequencyControlDTO buildFrequencyControlDTO(String key, FrequencyControl frequencyControl) {
        FrequencyControlDTO frequencyControlDTO = new FrequencyControlDTO();
        frequencyControlDTO.setKey(key);
        frequencyControlDTO.setTime(frequencyControl.time());
        frequencyControlDTO.setUnit(frequencyControl.unit());
        frequencyControlDTO.setCount(frequencyControl.count());
        return frequencyControlDTO;
    }

}
